#ifndef USBTRANSFERS_H
#define USBTRANSFERS_H

#include <libusb.h>
#include "tools.h"

// structures for dumping RAM
// request is sent to endpoint 2
struct InRequest
{
    char    type;           // 0x7e (Point-to-Point Protocol)
    u32     sig;            // 0x14125634 - big endian
    u32     offset;         // memory offset to read from - big endian
    u32     len;            // length of memory to read - big endian
    u16     crc16;          // 2 bytes that seem a big random.  maybe a checksum or something
    char    endTag;         // 0x7e
} __attribute__(( packed ));

// reply comes from endpoint 3
struct MemDumpResponse
{
    u32     sig;            // 0x15125623 - big endian
    u32     offset;         // memory offset - big endian
    u32     len;            // length of memory - big endian
    char    memory[];       // array of bytes that make up the payload
} __attribute__(( packed ));

// stuff for chucksumming requests
#define PPPINITFCS16 0xffff
#define PPPGOODFCS16    0xf0b8

u16 pppfcs16( register unsigned short fcs, const unsigned char *cp, register int len );
void DoFcs16( unsigned char *cp, int len );
bool CheckFcs( const u8* d, u32 len );
void EscapeMessage( const u8* inB, u8 *outBuf, u32 &len );
void UnEscapeMessage( u8* d, int &len );
void UnEscapeMessage( u8* s, u8* d, int &len );

// copies the request from ir to outbuf and escapes all the 0x7e and 0x7d except for the start and end
// it assumes outBuf is large enough for the escaped message
// returns the length of the escaped message
u32 EscapeInRequest( InRequest *ir, u8* outBuf );

// when talking to the phone, they send a command to e3 and it wont return until they send one to e2
// this function sends both commands and blocks until the timeout occurrs or both commands complete
int do_i3_bulk_transfer( struct libusb_device_handle *dev_handle,
                                unsigned char endpoint, unsigned char *buffer, int length,
                                int *transferred, unsigned int timeout,
                                unsigned char endpoint2, unsigned char *buffer2, int length2,
                                int *transferred2, unsigned int timeout2 );

// this is similar to the above function, except it sends the e2 command twice
int do_i3_bulk_transfer_multi( struct libusb_device_handle *dev_handle,
                                unsigned char endpoint, unsigned char *buffer, int length,
                                int *transferred, unsigned int timeout,
                                unsigned char endpoint2, unsigned char *buffer2, int length2,
                                int *transferred2, unsigned int timeout2 );

#endif // USBTRANSFERS_H
